﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using UI.ParentForm;
using UI.Lib.Factory;
using UI.Lib;
using UI.Test;
using System.Reflection;
using Components;
using Controls;
using UI.Sysset;
using DevComponents.DotNetBar;
using System.Threading;
using UI.CommonForm;
using System.Collections;
using System.IO;
using Com.Seezt.Skins;

namespace UI
{
    public partial class FrmMain : Form
    {
        public delegate void State(string msg, bool isError);
        public event State StateChange;
        FrmLoading frmLoading = null;//显示等待窗口
        private string guid = "";//登录标识
        private string userName = ""; //用户标识

        public FrmMain(string userName, string _guid)
        {
            InitializeComponent();

            Init(); //初始化属性

            guid = _guid;
            this.userName = userName;

            tmMain.Start();

            frmLoading = new FrmLoading();//显示等待窗口
        }

        void Init()
        {
            //设置字体
            this.menuMain.Font = this.sbNav.Font = stsBtm.Font = Global.AllFont;
        }

        private void PageInit()
        {
            //初始化状态栏信息
            tspUserName.Text = string.Format("当前登录者：{0}   所属部门：{1}   所属公司：{2}",
                userName + (string.IsNullOrEmpty(Context.User.Empname) ? "" : (" | " + Context.User.Empname)),
                (string.IsNullOrEmpty(Context.User.Depcode) ? "" : (Context.User.Depcode + " | " + Context.User.Depname)),
                (string.IsNullOrEmpty(Context.User.Comcode) ? "" : (Context.User.Comcode + " | " + Context.User.Comname))
                );

            this.Text = string.Format("{0}{1}({2})", this.Text, Context.Version, DateTime.Now.ToShortDateString());

            this.Update();
        }

        //页面被移除时，去掉服务器的用户标识
        private void FrmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            //删除登录文件标识
            string fileName = string.Concat(Context.ApplicationPath, "\\", userName);
            if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }
            CommonHelper.Entity.LoginOut(this.guid);

            if (e.CloseReason == CloseReason.UserClosing)
                Application.Exit();
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Validation.ToString(Context.GetValueByKey("exit")) != "auto")
            {
                if (MsgBox.Show(this, "提示", "确认退出本系统吗？", MessageBoxButtons.YesNo) != DialogResult.Yes)
                {
                    e.Cancel = true;
                }
                else
                {
                    Context.AddCache("EXIT", true);
                }
            }
        }

        private void tmMain_Tick(object sender, EventArgs e)
        {
            tmMain.Enabled = false;

            try
            {
                //检查更新
                AutoUpdaterHelper helper = new AutoUpdaterHelper();
                if (!helper.Update())
                {
                    MsgBox.Show(this, "存在新文件，您没有更新，请重新登录！", "提示");
                    Application.Exit();
                }
            }
            catch (PsException exp)
            {
                if (exp.ErrorNum == 1) CommonHelper.serverOut = true;
                MsgBox.ShowErrorMsg(this, exp.ErrMsg);
            }

            tmMain.Enabled = true;
        }

        private void txtNav_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                DoSearch();
            }
        }

        //在快速查询框中输入数字后，回车执行查询，打开对应的模块
        private void DoSearch()
        {
            string[] navKeys = this.txtNav.Value.ToString().Split('.');
            if (navKeys.Length < 1 || 0 == this.sbNav.Panels.Count) return;

            int panNum = Validation.ToInt(navKeys[0]); //Panel的数字

            if (panNum > this.sbNav.Panels.Count) return;
            //panel Name
            string panKey = string.Format("S{0}", panNum);
            if (!this.sbNav.Panels.Contains(panKey)) return;

            SideBarPanelItem preSelectedPan = this.sbNav.Panels[panKey] as SideBarPanelItem;
            this.sbNav.ExpandedPanel = preSelectedPan; //展开面板

            string itemName = navKeys.Length > 1 ? navKeys[1] : "0";
            if ("0" == itemName) return; //只展开组面板

            itemName = string.Format("{0}_{1}", panKey, itemName);
            if (!preSelectedPan.SubItems.Contains(itemName)) return;

            (preSelectedPan.SubItems[itemName] as ButtonItem).RaiseClick();
        }

        #region 系统菜单相关

        //加载菜单
        public void LoadMenuContext()
        {
            DateTime startTime = DateTime.Now;//记下开始时间 ， 如果读取菜单的整个过程小于2秒，则让等待窗口停留2秒

            this.OnStateChange("正在努力的尝试的提取菜单数据……", false);
            DataTable os = CommonHelper.Entity.GetCurrentPermision(); //得到当前用户的所有权限信息
            LogHelper.Entity.Out("提取权限");
            if (null == os || 0 == os.Rows.Count)
            {
                this.OnStateChange("您没有任何的权限，请联系管理员！", true);
                return;
            }

            this.OnStateChange("菜单数据提取成功，正在为您生成菜单……", false);
            DataView dv = new DataView(os);
            //过滤出当前父菜单下在所有子菜单数据(仅为下一层的)
            dv.RowFilter = "isroot=1";

            PsToolStripMenuItem topMenu = null; //根目录
            SideBarPanelItem sbItem = null;
            int nowNo = 0;
            for (int i = 0; i < dv.Count; i++) //生成根节点
            {
                //创建一个菜单项
                topMenu = new PsToolStripMenuItem();
                //给菜单赋Text值。也就是在界面上看到的值。
                topMenu.Text = dv[i]["modulename"].ToString();
                topMenu.ModuleName = dv[i]["modulecode"].ToString();//设置模块的编码
                topMenu.DefaultAction = dv[i]["pdact"].ToString();//设置默认的功能代码
                topMenu.Font = Global.AllFont;

                nowNo = i + 1;
                //创建左边的导航栏
                sbItem = new SideBarPanelItem("S" + (i + 1), nowNo + " " + topMenu.Text);
                sbItem.Tag = topMenu.ModuleName;
                sbItem.TextAlignment = eStyleTextAlignment.Near;

                //如果是有下级菜单则通过CreateSubMenu方法来创建下级菜单
                if (Validation.ToString(dv[i]["haschild"]) == "1")
                {
                    //以ref的方式将顶层菜单传递参数，因为他可以在赋值后再回传。－－也许还有更好的方法^_^.
                    CreateSubMenu(ref topMenu, Validation.ToString(dv[i]["modulecode"]), os, ref sbItem);
                }
                //显示应用程序中已打开的 MDI 子窗体列表的菜单项
                //menuMain.MdiWindowListItem = topMenu;
                //将递归附加好的菜单加到菜单根项上。
                menuMain.Items.Add(topMenu);
                this.sbNav.Panels.Add(sbItem);
            }

            this.OnStateChange("正在读取您的公司、部门等信息……", false);

            //取得当前用户相关的信息
            DataTable dtUser = CommonHelper.Entity.ExecFun("getuserbaseinfo", new KeyValuePair<string, object>("@usercode", userName));
            //LogHelper.Entity.Out("等到用户信息");
            Context.AddCommonInfo(dtUser); //保存用户标识

            this.OnStateChange("加载全局设置……", false);

            DataTable dtGlobs = CommonHelper.Entity.ExecFun("getglobsparam", new KeyValuePair<string, object>("@comcode", Context.realComcode),
                 new KeyValuePair<string, object>("@key", "___"));
            //LogHelper.Entity.Out("提取全局变量");
            if (null != dtGlobs && 0 != dtGlobs.Rows.Count)
            {
                Hashtable tbParam = new Hashtable();
                foreach (DataRow dp in dtGlobs.Rows) { tbParam.Add(Validation.ToString(dp["k"]), Validation.ToString(dp["v"])); }

                Context.AddGloblos(tbParam);
            }

            this.OnStateChange("全局设置加载完成……", false);

            DateTime endTime = DateTime.Now;
            TimeSpan ts = DateTime.Now.Subtract(startTime); //计算两个时间差
            if (ts.Seconds > 60) //大于30秒
            {
                this.OnStateChange("看来您的网络不是太好，建议您稍后再登录系统进行操作……", false);
                System.Threading.Thread.Sleep(1000 * 1); //让信息停留1秒，让用户看清楚
            }

            this.OnStateChange("主窗口加载完毕……", false);

            //加载共用菜单，不需要权限控制
            {
                topMenu = new PsToolStripMenuItem();
                topMenu.Text = "附加功能";
                topMenu.Name = "C_M_1";

                PsToolStripMenuItem item = new PsToolStripMenuItem();
                item.Name = topMenu.Name + "_1";
                item.Text = "修改密码";
                item.Click += new EventHandler(item_ChangePwd_Click);
                topMenu.DropDownItems.Add(item);

                ToolStripSeparator sptor = new ToolStripSeparator(); //分割线
                sptor.Name = topMenu.Name + "_l_1";
                topMenu.DropDownItems.Add(sptor);

                if (Context.IsSuperUser) //如果用户是超户，那么现实附加功能
                {
                    item = new PsToolStripMenuItem();
                    item.Name = topMenu.Name + "_4";
                    item.Text = "Session管理";
                    item.Click += new EventHandler(item_Session_Click);
                    topMenu.DropDownItems.Add(item);

                    sptor = new ToolStripSeparator(); //分割线
                    sptor.Name = topMenu.Name + "_l_2";
                    topMenu.DropDownItems.Add(sptor);
                }

                item = new PsToolStripMenuItem();
                item.Name = topMenu.Name + "_2";
                item.Text = "重载系统";
                item.Click += new EventHandler(item_Reload_Click);
                topMenu.DropDownItems.Add(item);

                item = new PsToolStripMenuItem();
                item.Name = topMenu.Name + "_3";
                item.Text = "退出系统";
                item.Click += new EventHandler(item_Exit_Click);
                topMenu.DropDownItems.Add(item);

                menuMain.Items.Add(topMenu);
            }

            PageInit();
        }

        /// <summary>
        /// 创建子菜单
        /// </summary>
        /// <param name="topMenu">父菜单项</param>
        /// <param name="ItemID">父菜单的ID</param>
        /// <param name="dt">所有菜单数据集</param>
        private void CreateSubMenu(ref PsToolStripMenuItem topMenu, string ItemID, DataTable dt, ref SideBarPanelItem sbItem)
        {
            DataView dv = new DataView(dt);
            //过滤出当前父菜单下在所有子菜单数据(仅为下一层的)
            dv.RowFilter = string.Format("parentcode='{0}'", ItemID);

            PsButtonItem sbBtnItem = null;
            PsToolStripMenuItem subMenu = null;
            int nowNo = 0;
            for (int i = 0; i < dv.Count; i++)
            {
                //创建子菜单项
                subMenu = new PsToolStripMenuItem();
                subMenu.Name = dv[i]["modulecode"].ToString();
                subMenu.Text = dv[i]["modulename"].ToString();
                subMenu.ModuleName = subMenu.Name;//设置模块的编码
                subMenu.DefaultAction = dv[i]["pdact"].ToString();//设置默认的功能代码
                subMenu.Font = Global.AllFont;

                nowNo = i + 1;
                sbBtnItem = new PsButtonItem(sbItem.Name + "_" + nowNo, sbItem.Name.Replace("S", "") + "." + nowNo + " " + subMenu.Text);
                sbBtnItem.Tag = topMenu.ModuleName;
                sbBtnItem.ModuleName = subMenu.ModuleName;
                sbBtnItem.DefaultAction = subMenu.DefaultAction;

                //如果还有子菜单则继续递归加载。
                if (Validation.ToString(dv[i]["haschild"]) == "1")
                {
                    //递归调用
                    CreateSubMenu(ref subMenu, Validation.ToString(dv[i]["modulecode"]), dt, ref sbItem);
                }
                else
                {
                    //扩展属性可以加任何想要的值。这里用formName属性来加载窗体。
                    subMenu.Tag = sbBtnItem.Tag = dv[i]["purl"].ToString();
                    //给没有子菜单的菜单项加事件。
                    subMenu.Click += new EventHandler(subMenu_Click);

                    //给没有子菜单的菜单项加事件。
                    sbBtnItem.Click += new EventHandler(sbBtnItem_Click);
                }

                //将菜单加到顶层菜单下。
                topMenu.DropDownItems.Add(subMenu);
                sbItem.SubItems.Add(sbBtnItem);
            }
        }

        void sbBtnItem_Click(object sender, EventArgs e)
        {
            PsButtonItem btnItem = sender as PsButtonItem;
            if (null == btnItem) return;
            //tag属性在这里有用到。
            OpenForm(Validation.ToString(btnItem.Tag), btnItem.ModuleName, btnItem.DefaultAction, btnItem.Text);
        }

        void item_Session_Click(object sender, EventArgs e)
        {
            OpenForm("Sysset.FrmSessionManager", "sessionmg", "V", "Session管理");
        }

        /// <summary>
        /// 菜单单击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void subMenu_Click(object sender, EventArgs e)
        {
            PsToolStripMenuItem menuItem = sender as PsToolStripMenuItem;
            if (null == menuItem) return;
            //tag属性在这里有用到。
            OpenForm(Validation.ToString(menuItem.Tag), menuItem.ModuleName, menuItem.DefaultAction, menuItem.Text);
        }

        #endregion

        #region 热键相关

        private void Form_Activated(object sender, EventArgs e)
        {
        }

        private void Form_Deactivate(object sender, EventArgs e)
        {
        }


        private void FrmMain_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.End:    //按下的是End == 进入查询 让文本框得到焦点
                    if (this.txtNav.Visible == true && e.Control) txtNav.Focus();
                    break;
                case Keys.Home:    //按下的是Home，Id号为104 == 执行查询
                    if (this.txtNav.Visible == true && e.Control) DoSearch();
                    break;
                case Keys.F4:    //按下的是F4，Id号为107 == 返回及关闭
                case Keys.Escape:
                    this.Close();
                    break;
                /* case 108:    //按下的是F5，Id号为108 == 调用子菜单
                     break;
                 case 109:    //按下的是F1，Id号为109 == 提示
                     break; */
            }
        }

        #endregion

        /// <summary>
        /// 点击菜单或导航栏打开具体的页面
        /// </summary>
        /// <param name="url"></param>
        /// <param name="modulename"></param>
        /// <param name="act"></param>
        private void OpenForm(string url, string modulename, string act, string winText)
        {
            if (CommonHelper.serverOut)
            {
                MsgBox.ShowErrorMsg(this, new PsException(5).ErrMsg);
                return;
            }

            if (Context.IsLoginOut)
            {
                MsgBox.ShowErrorMsg(this, new PsException(6).ErrMsg);
                return;
            }

            string assName = "UI";
            BaseForm frm = System.Reflection.Assembly.Load(assName).CreateInstance(string.Format("{0}.{1}", assName, url), true,
            BindingFlags.DeclaredOnly |
            BindingFlags.Public | BindingFlags.NonPublic |
            BindingFlags.Instance | BindingFlags.CreateInstance, null, new object[] { modulename, act }, null, null) as BaseForm;
            frm.Name = modulename;
            frm.WinText = winText;//设置标题

            if (OpenOnce(frm) && frm.IsInitOk)
            {
                frm.MdiParent = this;
                frm.WindowState = FormWindowState.Maximized;
                frm.Show();
            }
        }

        /// <summary>
        /// 窗口只让打开一次
        /// </summary>
        /// <param name="frm"></param>
        /// <returns></returns>
        private bool OpenOnce(Form frm)
        {
            foreach (Form mdifrm in MdiChildren)
            {
                if (frm.Name == mdifrm.Name)
                {
                    mdifrm.Activate();
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 当加载状态改变时触发
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="isError"></param>
        public virtual void OnStateChange(string msg, bool isError)
        {
            if (this.StateChange != null) { this.StateChange(msg, isError); } //调用事件
        }

        //修改密码
        void item_ChangePwd_Click(object sender, EventArgs e)
        {
            FrmChangePwd frm = new FrmChangePwd();
            frm.ShowDialog();
        }

        //重载系统
        void item_Reload_Click(object sender, EventArgs e)
        {
            //先清空菜单和导航条
            this.menuMain.Items.Clear();
            this.sbNav.Panels.Clear();
            this.Update();

            frmLoading.count = 1;
            frmLoading.startTime = DateTime.Now;
            frmLoading.StartPosition = FormStartPosition.CenterScreen;
            frmLoading.Show();

            this.StateChange += new FrmMain.State(frmLoading.SetPlan);//如果加载的状态改变时，同时现在是loading窗口上

            Thread thUI = new Thread(new ThreadStart(this.LoadMenuContext));
            thUI.Name = "Loading……";
            thUI.Priority = ThreadPriority.Highest;
            thUI.IsBackground = true;
            thUI.Start();

            thUI.Join();//等到显示Loading窗口的进程结束之后，才打开主页面

            if (!string.IsNullOrEmpty(frmLoading.Msg))
            {
                frmLoading.SetErrorMsg();
                System.Threading.Thread.Sleep(1000 * 3); //停顿3秒 结束
                CommonHelper.Entity.LoginOut(guid);
                Application.Exit();
            }
            else
            {
                frmLoading.Hide();
            }

            this.sbNav.Update();
        }

        //退出
        void item_Exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            CheckOrShowUpdateInfo(); //显示更新信息

            LeftWidth = this.bar1.Width;

            //工具栏控制权限
            CheckToolBar();
        }

        /// <summary>
        /// 显示更新信息
        /// </summary>
        void CheckOrShowUpdateInfo()
        {
            //读取更新信息
            string upath = string.Concat(Context.ApplicationPath, "\\", "u.dat");
            string uf = CommonUtil.GetInstance.LoadFromFile(upath);
            if (string.IsNullOrEmpty(uf)) return;

            //清空文件
            CommonUtil.GetInstance.SaveToFileOverride(upath, "");
            //将更新信息备份
            string ufbak = string.Concat(Context.ApplicationPath, "\\", "u.dat.bak");
            CommonUtil.GetInstance.SaveToFile(ufbak, uf);

            //显示更新信息面板
            FrmMessage msg = new FrmMessage("更新信息", uf);
            msg.Show();
        }

        private void bar1_ClientSizeChanged(object sender, EventArgs e)
        {
            LeftWidth = bar1.Width;
        }

        public static int LeftWidth = 0;

        private void CheckToolBar()
        {
            this.bar2.Visible = true;
            this.bar2.Height = 26;
            this.panBar.Size = new Size(this.panBar.Width, 53);
            bool hasControl = false;
            foreach (BaseItem bi in this.bar2.Items)
            {
                if (Validation.IsNull(bi.Tag))
                {
                    bi.Visible = false;
                    continue;
                }

                if (this.menuMain.Items.Find(Validation.ToString(bi.Tag), true).Length == 0)
                {
                    bi.Visible = false;
                    continue;
                }

                bi.Click += new EventHandler(bi_Click);

                hasControl = true;
            }

            if (hasControl == false) //隐藏工具栏
            {
                this.bar2.Visible = false;
                this.panBar.Size = new Size(this.panBar.Width, this.tabPageManager.Height);
            }
        }

        void bi_Click(object sender, EventArgs e)
        {
            BaseItem item = sender as BaseItem;

            ToolStripItem menu = this.menuMain.Items.Find(Validation.ToString(item.Tag), true)[0];

            menu.PerformClick(); //模拟点击菜单
        }
    }
}
